<template>
  <div
    id="container"
    :style="`height:${visibleHeight}px;overflow: auto;`"
    @scroll="throttleScroll"
  >
    <div :style="`height:${totalHeight}px;`">
      <div :style="`height:${topHeight}px`"></div>
      <div v-for="i in shownItem" :key="i.offset">
        <div class="section" :style="`height:${i.height}px`">
          <img :src="image" alt="" />
        </div>
      </div>
      <div :style="`height:${bottomHeight}px`"></div>
    </div>
  </div>
</template>

<script>
import { throttle } from 'lodash';
import './style.css';
import image from './assets/1.jpg';

let currentOffset = 0;
const visibleScreenCount = 3
export default {
  data() {
    return {
      image,
      topHeight: 0,
      bottomHeight: 0,
      totalHeight: 0,
      visibleHeight: 800,
      list: new Array(100).map((item, index) => index),
      scrollTop: 0,
      itemLayouts: [],
      shownItem: [],
    };
  },
  methods: {
    getItemLayout(item, index) {
      const ITEM_HEIGHT = 100 + Math.random() * 100;
      const offset = currentOffset;
      currentOffset += ITEM_HEIGHT;
      return {
        height: ITEM_HEIGHT,
        offset,
        index,
      };
    },
    onScroll(e) {
      this.scrollTop = document.getElementById('container').scrollTop;
      this.getShownItems();
    },
    throttleScroll: throttle(function onScroll(e) {
      this.scrollTop = document.getElementById('container').scrollTop;
      this.getShownItems();
    }, 100),
    getShownItems() {
      const items = this.itemLayouts.filter(
        (item) =>
          item.offset >= this.scrollTop &&
          item.offset <= this.scrollTop + this.visibleHeight * visibleScreenCount
      );
      this.shownItem = items;
      if (items.length > 0) {
        this.topHeight = items[0].offset;
        let bottomHeight = this.totalHeight -
          items[items.length - 1].offset -
          items[items.length - 1].height
        if (bottomHeight < items[items.length - 1].height) {
          bottomHeight = 0
        }
        this.bottomHeight = bottomHeight
      }
    },
  },
  created() {
    const arr = [];
    for (let i = 0; i < this.list.length; i++) {
      const item = this.list[i];
      arr.push(this.getItemLayout(item, i));
    }
    this.totalHeight = currentOffset;
    this.itemLayouts = arr;
    this.getShownItems();
  },
};
</script>

<style></style>
